﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.Xml;
using System.Reflection;
using BlueLotus7.ArchiveSystem.Interfaces;
using System.Globalization;

namespace BlueLotus7.ArchiveSystem.Common
{
    [DataContract]
    public abstract class BaseArchiveTask
    {
        [DataContract]
        public enum TaskStatus
        {
            [EnumMember]
            Ready = 0,
            [EnumMember]
            Doing = 1,
            [EnumMember]
            Done = 2,
            [EnumMember]
            FailedOrError = 10,
            [EnumMember]
            Waiting = 20,
            [EnumMember]
            Disabeld = 100
        }

        #region Fields

        [DataMember]
        public Guid Key
        {
            get;
            set;
        }

        [DataMember]
        public string DomainScopeCode
        {
            get;
            set;
        }

        [DataMember]
        public string TargetIdentity
        {
            get;
            set;
        }

        [DataMember]
        public TaskStatus Status
        {
            get;
            set;
        }

        #endregion

        public TaskExecutionRecord GenerateExecutionRecord()
        {
            return GenerateExecutionRecord(null);
        }

        public TaskExecutionRecord GenerateExecutionRecord(Exception exception)
        {
            TaskExecutionRecord record = new TaskExecutionRecord();
            record.IsSuccess = (exception == null);
            record.CreatedStamp = DateTime.Now;
            record.RecordKey = Guid.NewGuid();
            if (!record.IsSuccess)
            {
                record.Exception = FormatException(exception);
            }
            FillRecordInfo(record);

            return record;
        }

        protected virtual void FillRecordInfo(TaskExecutionRecord record)
        {
            //Nothing to do.
        }

        protected static string FormatException(Exception ex)
        {
            StringBuilder exDetails = new StringBuilder();

            exDetails.AppendFormat(CultureInfo.InvariantCulture, "Exception Type: {0}\r\n", ex.GetType().ToString());

            exDetails.AppendFormat(CultureInfo.InvariantCulture, "\r\nException Message: {0}", ex.Message);
            exDetails.AppendFormat(CultureInfo.InvariantCulture, "\r\n\r\nSource: {0}", ex.Source);
            exDetails.AppendFormat(CultureInfo.InvariantCulture, "\r\nSite: {0}", ex.TargetSite);
            exDetails.AppendFormat(CultureInfo.InvariantCulture, "\r\nStackTrace: {0}\r\n", ex.StackTrace);

            if (ex.InnerException != null)
                exDetails.AppendFormat(CultureInfo.InvariantCulture, "\r\n***** Inner Exception *****\r\n{0}", FormatException(ex.InnerException));

            return exDetails.ToString();
        }
    }

}
